package com.legendshop.openportal.sdk.validator;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.legendshop.openportal.sdk.annotation.EnumValid;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 枚举字段校验
 *
 * @author zibin
 */
@Slf4j
public class EnumValidator implements ConstraintValidator<EnumValid, Object> {

    /**
     * 枚举注解
     */
    private EnumValid annotation;

    private final static String GETTER = "get";

    @Override
    public void initialize(EnumValid constraintAnnotation) {
        this.annotation = constraintAnnotation;
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        boolean ignoreEmpty = annotation.ignoreEmpty();
        if (ObjectUtil.isEmpty(value)) {
            if (ignoreEmpty) {
                return Boolean.TRUE;
            }

            log.info("参数为空");
            return Boolean.FALSE;
        }
        Class<?> targetClass = annotation.target();
        if (!targetClass.isEnum()) {
            log.error("targetClass is not a enum class. {}", targetClass);
            return Boolean.FALSE;
        }
        try {
            Object[] objects = targetClass.getEnumConstants();
            // 字段名称必须为value，并且提供get方法
            String methodName = StrUtil.upperFirstAndAddPre(annotation.targetField(), GETTER);
            Method method = targetClass.getMethod(methodName);
            for (Object obj : objects) {
                Object code = method.invoke(obj);
                if (ObjectUtil.equal(value, code)) {
                    return Boolean.TRUE;
                }
            }
            return Boolean.FALSE;
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            log.error("EnumValidator call 'GET' method exception.", e);
            return Boolean.FALSE;
        }
    }
}
